package com.prawn.monitor.service;

import java.sql.Date;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import java.util.Map;

import javax.persistence.criteria.CriteriaBuilder;
import javax.persistence.criteria.CriteriaQuery;
import javax.persistence.criteria.Expression;
import javax.persistence.criteria.Predicate;
import javax.persistence.criteria.Root;
import javax.persistence.criteria.Selection;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Sort;
import org.springframework.data.jpa.domain.Specification;
import org.springframework.stereotype.Service;

import util.IdWorker;

import com.prawn.monitor.dao.MeteorologicalDataDao;
import com.prawn.monitor.pojo.MeteorologicalData;

/**
 * 服务层
 *
 * @author Administrator
 */
@Service
public class MeteorologicalDataService {

    @Autowired
    private MeteorologicalDataDao meteorologicalDataDao;

    @Autowired
    private IdWorker idWorker;

    /**
     * 查询全部列表
     *
     * @return
     */
    public List<MeteorologicalData> findAll() {
        return meteorologicalDataDao.findAll();
    }




    /**
     * 条件查询+分页
     *
     * @param whereMap
     * @param page
     * @param size
     * @return
     */
    public Page<MeteorologicalData> findSearch(Map whereMap, int page, int size) {
        Specification<MeteorologicalData> specification = createSpecification(whereMap);
        Sort sort=new Sort(Sort.Direction.ASC,"acquisitionTime");
        PageRequest pageRequest = PageRequest.of(page - 1, size,sort);

        return meteorologicalDataDao.findAll(specification, pageRequest);
    }
    /**
     * 预测需要的源数据
     *
     * @param whereMap
     * @param page
     * @param size
     * @return
     */
    public Page<Double> querySource(Map whereMap, int page, int size) {
        PageRequest pageRequest = PageRequest.of(page - 1, size);
        return meteorologicalDataDao.querySource((String)whereMap.get("checkItemName"), (String)whereMap.get("equipmentId"),(String)whereMap.get("startTime"),(String)whereMap.get("endTime"),pageRequest);
    }




    /**
     * 条件查询
     *
     * @param whereMap
     * @return
     */
    public List<MeteorologicalData> findSearch(Map whereMap) {
        Specification<MeteorologicalData> specification = createSpecification(whereMap);
        Sort sort=new Sort(Sort.Direction.ASC,"acquisitionTime");
        return meteorologicalDataDao.findAll(specification,sort);
    }

    /**
     * 根据ID查询实体
     *
     * @param id
     * @return
     */
    public MeteorologicalData findById(String id) {
        return meteorologicalDataDao.findById(id).get();
    }

    /**
     * 增加
     *
     * @param meteorologicalData
     */
    public void add(MeteorologicalData meteorologicalData) {
        meteorologicalData.setId(idWorker.nextId() + "");
        meteorologicalDataDao.save(meteorologicalData);
    }

    /**
     * 批量增加
     *
     * @param
     */
    public void addList(List<MeteorologicalData> ls) {
        if (ls == null || ls.size() == 0) {
            return;
        }
        for (MeteorologicalData meteorologicalData : ls) {

            meteorologicalDataDao.save(meteorologicalData);
        }
    }


    /**
     * 修改
     *
     * @param meteorologicalData
     */
    public void update(MeteorologicalData meteorologicalData) {
        meteorologicalDataDao.save(meteorologicalData);
    }

    /**
     * 删除
     *
     * @param id
     */
    public void deleteById(String id) {
        meteorologicalDataDao.deleteById(id);
    }

    /**
     * 动态条件构建
     *
     * @param searchMap
     * @return
     */
    private Specification<MeteorologicalData> createSpecification(Map searchMap) {

        return new Specification<MeteorologicalData>() {

            @Override
            public Predicate toPredicate(Root<MeteorologicalData> root, CriteriaQuery<?> query, CriteriaBuilder cb) {
                List<Predicate> predicateList = new ArrayList<Predicate>();

                // id
                if (searchMap.get("id") != null && !"".equals(searchMap.get("id"))) {
                    predicateList.add(cb.equal(root.get("id").as(String.class),  (String) searchMap.get("id")));
                }
                // 所属设备编号
                if (searchMap.get("equipmentId") != null && !"".equals(searchMap.get("equipmentId"))) {
                    predicateList.add(cb.equal(root.get("equipmentId").as(String.class),  (String) searchMap.get("equipmentId") ));
                }
                // 所属基地id
                if (searchMap.get("baseId") != null && !"".equals(searchMap.get("baseId"))) {
                    predicateList.add(cb.equal(root.get("baseId").as(String.class),  (String) searchMap.get("baseId") ));
                }
                // mV
                if (searchMap.get("electricEnergyUnit") != null && !"".equals(searchMap.get("electricEnergyUnit"))) {
                    predicateList.add(cb.equal(root.get("electricEnergyUnit").as(String.class),  (String) searchMap.get("electricEnergyUnit") ));
                }
                // Lux
                if (searchMap.get("illuminationUnit") != null && !"".equals(searchMap.get("illuminationUnit"))) {
                    predicateList.add(cb.equal(root.get("illuminationUnit").as(String.class),  (String) searchMap.get("illuminationUnit") ));
                }
                // m/s
                if (searchMap.get("windSpeedUnit") != null && !"".equals(searchMap.get("windSpeedUnit"))) {
                    predicateList.add(cb.equal(root.get("windSpeedUnit").as(String.class),  (String) searchMap.get("windSpeedUnit") ));
                }
                // 度
                if (searchMap.get("windDirectUnit") != null && !"".equals(searchMap.get("windDirectUnit"))) {
                    predicateList.add(cb.equal(root.get("windDirectUnit").as(String.class),  (String) searchMap.get("windDirectUnit") ));
                }
                // ℃
                if (searchMap.get("airTemperatureUnit") != null && !"".equals(searchMap.get("airTemperatureUnit"))) {
                    predicateList.add(cb.equal(root.get("airTemperatureUnit").as(String.class),  (String) searchMap.get("airTemperatureUnit") ));
                }
                // %
                if (searchMap.get("humidityUnit") != null && !"".equals(searchMap.get("humidityUnit"))) {
                    predicateList.add(cb.equal(root.get("humidityUnit").as(String.class),  (String) searchMap.get("humidityUnit") ));
                }
                // mm
                if (searchMap.get("rainUnit") != null && !"".equals(searchMap.get("rainUnit"))) {
                    predicateList.add(cb.equal(root.get("rainUnit").as(String.class),  (String) searchMap.get("rainUnit") ));
                }
                // ℃
                if (searchMap.get("soilTemperatureUnit") != null && !"".equals(searchMap.get("soilTemperatureUnit"))) {
                    predicateList.add(cb.equal(root.get("soilTemperatureUnit").as(String.class),  (String) searchMap.get("soilTemperatureUnit") ));
                }
                // %
                if (searchMap.get("soiMoistureUnit") != null && !"".equals(searchMap.get("soiMoistureUnit"))) {
                    predicateList.add(cb.equal(root.get("soiMoistureUnit").as(String.class),  (String) searchMap.get("soiMoistureUnit") ));
                }
                // 
                if (searchMap.get("CAMUnit") != null && !"".equals(searchMap.get("CAMUnit"))) {
                    predicateList.add(cb.equal(root.get("CAMUnit").as(String.class),  (String) searchMap.get("CAMUnit") ));
                }
                // 标记删除
                if (searchMap.get("deleted") != null && !"".equals(searchMap.get("deleted"))) {
                    predicateList.add(cb.equal(root.get("deleted").as(String.class),  (String) searchMap.get("deleted") ));
                }
                // 气象设备工作状态0（关闭）1（工作中）2（故障）
                if (searchMap.get("equipmentWorking") != null && !"".equals(searchMap.get("equipmentWorking"))) {
                    predicateList.add(cb.equal(root.get("equipmentWorking").as(String.class),  (String) searchMap.get("equipmentWorking") ));
                }

                // 日期
                if (searchMap.get("startTime") != null && !"".equals(searchMap.get("startTime"))) {
                    try {
                        SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd hh:mm:ss");
                        predicateList.add(cb.greaterThanOrEqualTo(root.get("acquisitionTime").as(Date.class), dateFormat.parse((String) searchMap.get("startTime"))));

                        if (searchMap.get("endTime") != null && !"".equals(searchMap.get("endTime"))) {
                            predicateList.add(cb.lessThanOrEqualTo(root.get("acquisitionTime").as(Date.class), dateFormat.parse((String) searchMap.get("endTime"))));
                        }
                    } catch (ParseException e) {
                        e.printStackTrace();
                    }
                }

                return cb.and(predicateList.toArray(new Predicate[predicateList.size()]));

            }
        };

    }


}
